﻿#region GNU General Public License
// XEdit2D - XNA 2D Asset Editor
// Copyright (C) 2010  HurlBat Games

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace HurlBat.XEdit2D
{
    public partial class Animations : UserControl, IAnimationsControl
    {
        List<HurlBat.Data2D.Graphics.Animation> animations = new List<HurlBat.Data2D.Graphics.Animation>();
        List<Bitmap> playingAnimation = new List<Bitmap>();
        int playingFrame = 0;
        PictureBox player = null;
        Timer timer = null;

        IMainForm f = null;
        IMainForm Form
        {
            get
            {
                if (f == null) f = (IMainForm)this.FindForm();
                return f;
            }
        }

        public Animations()
        {
            InitializeComponent();
        }

        private void listAnimations_DoubleClick(object sender, EventArgs e)
        {
            if (listAnimations.SelectedIndices.Count > 1) return;
            HurlBat.Data2D.Graphics.Animation anim = animations[listAnimations.SelectedIndices[0]];
            if (player == null)
            {
                player = new PictureBox();
                player.Dock = DockStyle.Fill;
                pnlPlayer.Controls.Add(player);
            }

            pnlPlayer.Height = anim.Frames[0].Location.Height;
            playingAnimation = new List<Bitmap>();
            playingFrame = 0;
            foreach (HurlBat.Data2D.Graphics.Image f in anim.Frames)
                playingAnimation.Add(Util.Crop(Image.FromFile(f.TextureName),
                    new Rectangle(f.Location.X, f.Location.Y, f.Location.Width, f.Location.Height)));

            if (timer == null)
            {
                timer = new Timer();
                timer.Interval = 1000 / 30;
                timer.Tick += new EventHandler(timer_Tick);
            }
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            playingFrame++;
            if (playingFrame == playingAnimation.Count)
                playingFrame = 0;
            player.Image = playingAnimation[playingFrame];
        }

        private void toolAnimationSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog svDlg = new SaveFileDialog();
            if (svDlg.ShowDialog() != DialogResult.OK) return;

            XmlSerializer serializer = new XmlSerializer(typeof(List<HurlBat.Data2D.Graphics.Animation>));
            TextWriter textWriter = new StreamWriter(svDlg.FileName);
            serializer.Serialize(textWriter, animations);
            textWriter.Close();
        }

        private void toolRemoveAnimations_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(
                string.Format("Are you sure you want to remove {0} animations ?",
                listAnimations.SelectedItems.Count),
                "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes)
                return;

            foreach (ListViewItem i in listAnimations.SelectedItems)
                listAnimations.Items.Remove(i);
            listAnimations.SelectedItems.Clear();
        }

        private void toolSelectAllAnimations_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < listAnimations.Items.Count; i++)
                listAnimations.Items[i].Selected = true;
        }

        private void listAnimations_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool toEnable = listAnimations.Items.Count > 0 && listAnimations.SelectedItems.Count > 0;
            toolAnimationRemove.Enabled = toEnable;
            toolCharacterCreate.Enabled = toEnable;
            //toolStatusLabelLeft.Text = string.Format("{0} item(s) selected out of {1}",
            //    listAnimations.SelectedItems.Count, listAnimations.Items.Count);
        }

        private void toolCharacterCreate_Click(object sender, EventArgs e)
        {
            CreateCharacter charDlg = new CreateCharacter();
            if (charDlg.ShowDialog() != DialogResult.OK) return;

            HurlBat.Data2D.Graphics.Character c = new HurlBat.Data2D.Graphics.Character(charDlg.CharacterName);
            Image cImage = null;
            foreach (ListViewItem i in listAnimations.SelectedItems)
            {
                if (cImage == null) cImage = listAnimations.LargeImageList.Images[i.ImageIndex];
                HurlBat.Data2D.Graphics.Animation currentAnimation = animations.Find(
                    delegate(HurlBat.Data2D.Graphics.Animation a)
                    {
                        return a.Name == i.Text;
                    });
                string action = string.Empty;
                foreach (string a in Globals.AppStore.CharacterActions)
                {
                    Regex re = new Regex(string.Format(@"(\W|^){0}(\W|$)", a), RegexOptions.IgnoreCase);
                    if (re.IsMatch(currentAnimation.Name))
                    {
                        action = a;
                        break;
                    }
                }
                string direction = string.Empty;
                foreach (string d in Globals.Directions[Globals.AppStore.CharacterType])
                {
                    Regex re = new Regex(string.Format(@"(\W|^){0}(\W|$)", d), RegexOptions.IgnoreCase);
                    if (re.IsMatch(currentAnimation.Name))
                    {
                        direction = d;
                        break;
                    }
                }
                c.Animations.Add(new HurlBat.Data2D.Graphics.DirectionalAnimation(currentAnimation, action, direction));

                if (Globals.AppStore.RemoveAnimations)
                {
                    animations.RemoveAll(
                        delegate(HurlBat.Data2D.Graphics.Animation a)
                        {
                            return a.Name == i.Text;
                        });
                    listAnimations.LargeImageList.Images.RemoveByKey(i.ImageKey);
                    listAnimations.Items.Remove(i);
                }
            }
            Form.CharactersControl.ResetImageList(70, 70);
            Form.CharactersControl.AddCharacter(c, cImage);
            Form.SwitchTab(TabType.Characters);
        }

        public void ResetImageList(int width, int height)
        {
            listAnimations.LargeImageList = new ImageList();
            listAnimations.LargeImageList.ImageSize = new Size(width, height);
        }

        public void AddAnimation(HurlBat.Data2D.Graphics.Animation anim, Bitmap image)
        {
            animations.Add(anim);
            listAnimations.LargeImageList.Images.Add(image);
            ListViewItem item = new ListViewItem(anim.Name,
                listAnimations.LargeImageList.Images.Count - 1);
            item.Tag = (animations.Count - 1).ToString();
            listAnimations.Items.Add(item);
        }
    }
}
